#ifndef __SERVER_H
#define __SERVER_H

#include "ae.h"
#include "sds.h"
#include "adlist.h"

#define C_OK                    0
#define C_ERR                   -1

#define LOG_DEBUG 1
#define LOG_INFO 2
#define LOG_NOTICE 3
#define LOG_WARNING 4

/* Log levels */
#define LL_DEBUG 0
#define LL_VERBOSE 1
#define LL_NOTICE 2
#define LL_WARNING 3
#define LL_RAW (1<<10) /* Modifier to log without timestamp */

#define LOG_MAX_LEN    1024 /* Default maximum length of syslog messages.*/

#define CONFIG_BINDADDR_MAX 16

#define CONFIG_MIN_RESERVED_FDS 32
#define CONFIG_FDSET_INCR (CONFIG_MIN_RESERVED_FDS+96)

#define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */

#define REDIS_REPLY_CHUNK_BYTES (16*1024)
#define REDIS_IOBUF_LEN         (1024*16)  /* Generic I/O buffer size */

struct redisServer {
    char* bindaddr; /* Addresses we should bind to */
    int port;                   /* TCP listening port */
    int tcp_backlog;            /* TCP listen() backlog */
    int ipfd;                   /* TCP socket file descriptors */
    unsigned int maxclients;
    // 一个链表，保存了所有客户端状态结构
    list *clients;              /* List of active clients */

    aeEventLoop *el;
};

typedef struct redisClient {
    // 套接字描述符
    int fd;

    // 查询缓冲区
    sds querybuf;

}redisClient;


extern struct redisServer server;


int createSocketAcceptHandler(int sfd, aeFileProc *accept_handler);
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask);
int listenToPort(int port, int *fd);

void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
void freeClient(redisClient *c);

#ifdef __GNUC__
void _serverLog(int level, const char *fmt, ...)
    __attribute__((format(printf, 2, 3)));
#else
void _serverLog(int level, const char *fmt, ...);
#endif
void serverLogRaw(int level, const char *msg);

/* Use macro for checking log level to avoid evaluating arguments in cases log
 * should be ignored due to low level. */
#define serverLog(level, ...) do {\
        _serverLog(level, __VA_ARGS__);\
    } while(0)

#endif